package com.ruoyi.common.utils;

import com.ruoyi.common.constant.SyncCommands;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.function.Supplier;

import static com.ruoyi.common.constant.SyncCommands.COMMAND_NAME_MAP;


/**
 *
 *@author wangkk
 *@date 2025-02-11 10:58
 */
@Component
@RequiredArgsConstructor
public class RedisCacheTemplate {

    private final RedisTemplate<String, String> redisTemplate;

    /**
     * 缓存指定命令的数据内容
     * @param command 操作命令
     * @param value 数据内容
     */
    public <T> T cacheCommandContent(int command, T value) {
        final var key = COMMAND_NAME_MAP.get(command);
        if (!StringUtils.hasText(key)) {
            throw new IllegalArgumentException("不支持的命令码");
        }
        redisTemplate.boundValueOps(key).set(JacksonUtils.writeValueAsString(value));
        return value;
    }

    /**
     * 缓存指定命令的数据内容
     * @param command 操作命令
     * @param valueSupplier 数据内容生产
     */
    public <T> T cacheCommandContent(int command, Supplier<T> valueSupplier) {
        return cacheCommandContent(command, valueSupplier.get());
    }

    /**
     * 缓存指定命令的数据内容,只有在redis中没有对应的cache时才缓存
     * @param command 操作命令
     * @param valueSupplier 数据内容生产
     */
    public <T> T getCacheIfPresentOrCache(int command, Supplier<T> valueSupplier, Class<T> clazz) {
        final T cacheContent = getCacheCommandContent(command, clazz);
        if (cacheContent == null) {
            return cacheCommandContent(command, valueSupplier.get());
        }
        return cacheContent;
    }

    /**
     * 获取指定命令缓存的数据内容
     * @param command 操作命令
     */
    public <T> T getCacheCommandContent(int command, Class<T> clazz) {
        final var key = COMMAND_NAME_MAP.get(command);
        if (!StringUtils.hasText(key)) {
            throw new IllegalArgumentException("不支持的命令码");
        }
        final String content = redisTemplate.boundValueOps(key).get();
        if (StringUtils.hasText(content)) {
            return JacksonUtils.readValue(content, clazz);
        }
        return null;
    }


}
